<script lang="ts" setup>
import { withDefaults, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { UploadProps } from 'element-plus'
import type { UploaderProps } from './interface'
defineOptions({
  name: 'UploadComponent',
  inheritAttrs: false,
})

const emit = defineEmits<{
  (e: 'upload-success', url: string): void
  (e: 'upload-error', error: string): void
}>()

const props = withDefaults(defineProps<Partial<UploaderProps>>(), {
  name: 'file',
  method: 'post',
  multiple: false,
  headers: () => ({}),
  accept: 'image/*',
})

const model = defineModel({ default: '' })

const loading = ref(false)
const url = ref('')
// 0 - 未上传, 1 - 上传成功, 2 - 上传失败
const isUpload = ref<'0' | '1' | '2'>('0')
const uploaderError = (err: Error) => {
  console.error('Upload error:', err)
  loading.value = false
  isUpload.value = '2'
  model.value = ''
  ElMessage.error('上传失败，请重试')
  emit('upload-error', err.message)
}

const uploaderSuccess: UploadProps['onSuccess'] = (response: any) => {
  loading.value = false
  if (response.code !== 200) {
    ElMessage.error(response.message || '上传失败，请重试')
    isUpload.value = '2'
    model.value = ''
    emit('upload-error', response.message || '上传失败')
    return
  }
  isUpload.value = '1'
  url.value = response.data.url || ''
  model.value = url.value
  emit('upload-success', url.value)
}
</script>

<template>
  <div class="upload-container" v-loading="loading">
    <el-upload
      class="upload-component"
      action="/api/upload/qn"
      v-bind="props"
      :on-error="uploaderError"
      :on-success="uploaderSuccess"
      :before-upload="() => (loading = true)"
    >
      <el-image
        v-if="isUpload === '1'"
        :src="url"
        fit="cover"
        class="uploader-image"
      />
      <el-icon v-else class="uploader-icon"><Plus /></el-icon>
      <template #tip>
        <div class="uploader-tip">
          <span v-if="isUpload === '1'" style="color: #67c23a">
            文件上传成功
          </span>
          <span v-else-if="isUpload === '2'" style="color: rgb(248 113 113)">
            文件上传失败
          </span>
          <span v-else>点击上方上传文件</span>
        </div>
      </template>
    </el-upload>
  </div>
</template>

<style lang="scss" scoped>
.upload-container {
  .upload-component {
    width: 178px;
    height: 178px;

    :deep(.el-upload) {
      width: 100%;
      height: 100%;
      border: 1px dashed #4c4d4f;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: 0.2s;

      &:hover {
        border-color: #409eff;
      }
    }

    .uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      text-align: center;
    }

    .uploader-tip {
      margin-top: 10px;
      font-size: 12px;
      color: #fff;
      text-align: center;

      span {
        text-overflow: ellipsis;
        overflow: hidden;
        white-space: nowrap;
      }
    }
  }
}
</style>
